home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / timer11.zip / READ.ME < prev    next >
Text File  |  1992-04-21  |  13KB  |  294 lines

  1.  
  2.                         The Zen Timer Library
  3.                         =====================
  4.  
  5.                             Version 1.1
  6.  
  7. This is a 'C' callable library for timing code fragments with an accuracy of
  8. better than 10 microseconds (less when using the long period zen timer). The
  9. code was originally written by Michael Abrash for his book "Zen of Assembly
  10. language - Volume I, Knowledge". I modified the code and made it into a 'C'
  11. callable library and added the utility routines LZTimerCount() and
  12. PZTimerCount() to return an unsigned long integer representing the timed
  13. count in microseconds, and a set of C++ wrapper classes.
  14.  
  15. This new version include a new Ultra Long Period timer that can be used
  16. to time code that takes up to 24 hours to execute with an accuracy of 1/10th
  17. of a second. I have fixed the long period Zen Timer so that you can now
  18. time across a midnight boundary correctly, and I have added a number of
  19. C++ classes that provided a common interface to the timing routines.
  20.  
  21. Note also that this new version is memory model dependant whereas the old
  22. one was memory model independant.
  23.  
  24.                          Using the timer
  25.                          ---------------
  26.  
  27. To use the timer, isolate the piece of code you wish to time and bracket
  28. it with calls to PZTimerOn (LZTimerOn respectively) and PZTimerOff (LZTimerOff
  29. respectively). You can either call PZTimerReport (LZTimerReport respectively)
  30. which will display the count on the standard output device, or you can call
  31. PZTimerCount (LZTimerCount respectively) to obtain the count use it from
  32. within your C program. For example:
  33.  
  34. int i;
  35.  
  36. void main(void)
  37. {
  38.     LZTimerOn();
  39.     for (i = 0; i < 20000; i++)
  40.         i = i;                      /* Do some work */
  41.     LZTimerOff();
  42.     LZTimerReport();
  43. }
  44.  
  45. shows the simplest way to use the timer. The file "main.c" contains code
  46. to test both the precision and long period timers, so have a look at it to
  47. get an idea of how to use the timer.
  48.  
  49. The precision timer gives the most accurate results, but can only be
  50. used for code that executes in less than 54ms, and you CANNOT turn
  51. interrupts on while the code is being timed (if you code goes into an
  52. infinite loop while using the precision timer you will need to reach for
  53. that elusive reset switch :-). Personally the long period timer is
  54. accurate enough for me and I generally use this exclusively.
  55.  
  56. One point to note when using the long period time however, interrupts
  57. are ON while this timer executes. This means that every time you hit a key
  58. or move the mouse, the timed count will be longer that normal. Thus you
  59. should avoid hitting any keys or moving the mouse while timing code fragments
  60. if you want highly accurate results. It is also a good idea to insert a
  61. delay of about 1-2 seconds before turning the long period timer on if
  62. a key has just been pressed by the user (this includes the return key used
  63. to start the program from the command line!). Otherwise you may measure the
  64. time taken by the keyboard ISR to process the upstroke of the key that was
  65. just pressed.
  66.  
  67. In this new version there is now an Ultra Long Period timer that can
  68. be used to time code that takes up to 24 hours to execute. There are two
  69. routines that are used to accomplish this - ULZReadTime() and
  70. ULZElapsedTime(). The way to use these routines is simple:
  71.  
  72. void main(void)
  73. {
  74.     ulong   start,finish,time;
  75.  
  76.     start = ULZReadTime();
  77.  
  78.     /* Do something useful in here */
  79.  
  80.     finish = ULZReadTime();
  81.     time = ULZElapsedTime(start,finish);
  82. }
  83.  
  84. Calling ULZReadTime() latches the current timer count and returns it.
  85. You call ULZElapsedTime() to compute the time difference between the start
  86. and finishing times, which is returned in 1/10ths of a second.
  87.  
  88.                         Using the C++ interface
  89.                         -----------------------
  90.  
  91. If you are using C++, you can use the C++ wrapper classes that provide
  92. a simpler and common interface to all of the three timing routine (precision,
  93. long period and ultra long period). There are three classes that are used
  94. for this:
  95.  
  96.     PZTimer     - C++ Class to access the Precision Zen Timer
  97.     LZTimer     - C++ Class to access the Long Period Zen Timer
  98.     ULZTimer    - C++ Class to access the Ultra Long Period Zen Timer
  99.  
  100. Each class provides the following member functions:
  101.  
  102. start() member function
  103. -----------------------
  104.  
  105. The start() member function is called to start the timer counting. It
  106. does not modify the internal state of the timer at all.
  107.  
  108.  
  109. stop() member function
  110. ----------------------
  111.  
  112. The stop() member function is called to stop the timer from counting and
  113. to update the internal timer count. The internal timer count is the total
  114. amout of time that the timer has been running since the last call to
  115. reset() or restart() so it is cumulative.
  116.  
  117. reset() member function
  118. -----------------------
  119.  
  120. The reset() member function resets the internal state of the timer to a
  121. zero count and no overflow. This should be called to zero the state of the
  122. timer before timing a piece of code. Note that the reset operation is
  123. performed every time that a new instance of one of the timer classes is
  124. created.
  125.  
  126. restart() member function
  127. -------------------------
  128.  
  129. The restart() member function simply resets the timers internal state to
  130. a zero count and begins timing.
  131.  
  132. count() member function
  133. -----------------------
  134.  
  135. The count() member function returns the current timer count, which will
  136. be in fractions of a second. You can use the resolution() member function
  137. to determine how many counts there are in a second so you can convert it
  138. to a meaningful value. Use this routine if you wish to manipulate and display
  139. the count yourself. If the timer has overflowed while it was timing, this
  140. member function will return a count of 0xFFFFFFFF (-1 signed).
  141.  
  142. overflow() member function
  143. --------------------------
  144.  
  145. The overflow() member function will return true if the timer has overflowed
  146. while it was counting.
  147.  
  148. resolution() member function
  149. ----------------------------
  150.  
  151. The resolution() member function returns the number of timer counts that
  152. represent a second, so you can convert the count returned by the count()
  153. member function to a time.
  154.  
  155. operator << () friend function
  156. ------------------------------
  157.  
  158. This a convenience function that outputs a formatted string to a C++
  159. output stream that represents the value of the internal timer count in
  160. seconds. The string represents the time to the best accuracy possible with
  161. the timer being used.
  162.  
  163. The file main.cpp in the distribution gives an example of how to use the
  164. different timer classes.
  165.  
  166. Restrictions
  167. ------------
  168.  
  169. When using the precision timer class, you must ensure that there will be
  170. less than 54 ms between each call to start() and stop() or an overflow
  171. will result. The total cumulative time can be up to approx. 1 hour 10 mins.
  172.  
  173. The Long Period timer class also has a cumulative limit of approx. 1 hour
  174. 10 mins but this can be timed with only a single call to start() and stop().
  175.  
  176. When using the Ultra Long Period timer class you must ensure that no
  177. more than 24 hours elapses between calls to start() and stop() or you will
  178. get invalid result(). There is no way that we can reliably detect this
  179. so the timer will quietly give you a value that is much less than it should
  180. be. However, the total cumulative limit for this timer is about 119,000
  181. hours which should be enough for most practial purposes, but you must
  182. ensure that no more than 24 hours elapses between calls to start() and
  183. stop(). If you wish to use the timer for applications like ray tracing,
  184. then calling then latching the timer after every 10 scanlines or so should
  185. ensure that this criteria is met.
  186.  
  187. You can only have one instance of the Precision and Long Period timers
  188. running at any one time, but you can have mutiple instance of the ultra
  189. long period timer running.
  190.  
  191. Notes on compiling the library
  192. ------------------------------
  193.  
  194.    The library was compiled using Borland C++ 3.0 and Turbo Assembler 3.0.
  195. The code will NOT assemble under MASM, since it is written using
  196. Turbo Assemblers IDEAL mode syntax. You will need to modify it significantly
  197. to get it to assemble under MASM.
  198.  
  199.    I write all my code with 4 space tabs, so if you wish to view the source
  200. code the way I see it :-), you will need to set you editor to 4 space tabs
  201. (even the .ASM files use 4 space tabs). Alternatively you can view the
  202. source code files with "m.exe" included in the archive, a more replacement
  203. that I have written. It automatically expands tabs to 4 spaces (or any
  204. size you like with the -t option).
  205.  
  206.    The long period Zen Timer has been assembled to run on all computers,
  207. including the IBM PS/2 range of computers whose timer chips are not
  208. 100% compatible with the 8253. If you have read Michael's book, or you
  209. have had a look at the source code for the long period timer, you will
  210. know that you can re-assemble it with the PS2 equate set to 0 which will
  211. give more accurate results on computers with 100% compatible 8253 timer
  212. chips (note that this does not affect the precision Zen Timer - this works
  213. on all computers). I personally leave the PS2 equate set to 1, so that my
  214. code will work on any computer. Occasionally (and this is very rare - it
  215. has happend only once in the 3 odd months I have been using this code),
  216. the timer count will be out by 54 ms, but I find that I can live with
  217. this.
  218.  
  219.    The makefile included in the distribution is set up to build the library
  220. on my computer, but it should be very easy to modify for another installation
  221. (it took me five minutes to move it from my old 286 machine to my new
  222. 486/33 with a larger hard disk!). Consult the makefile to see how to do it.
  223. To build all of the memory model libraries, use the "buildall.bat" batch
  224. file. Note that the makefiles expect the presence to two makefile utilties
  225. that I always use. They are in the 'makefile.zip' archive as both source
  226. and executable versions.
  227.  
  228.    I have included the turboc.cfg file that I use to compile code from
  229. the command line using Borland C++ 3.0. You will need to modify the include
  230. file and library file directories for your system. If you have an earlier
  231. version of Borland C++, or Turbo C++ then most of the optimisation switches
  232. will not be valid.
  233.  
  234. Files in this archive
  235. ---------------------
  236.  
  237. This archive contains stored subdirectories so you should have unzipped it
  238. with the -d option, otherwise all of the following files will be in
  239. the same directory.
  240.  
  241.     buidall.bat         - Batch file to build all memory model libraries
  242.     debug.h             - Header file for portable code (you need this)
  243.     lztest.asm          - Shell program for timing assembler code
  244.     lztime.bat          - Batch file to automate assembler code timing
  245.     lztimer.asm         - Long Period Zen Timer source code
  246.     main.c              - Sample program source code
  247.     main.cpp            - Sample C++ class interface code
  248.     makefile            - Makefile for the Zen Timer library
  249.     makeutil.zip        - Archive containing makefile utilities (needed)
  250.     model.mac           - Memory model independant macros for TASM
  251.     pztest.asm          - Shell program for timing assemble code
  252.     pztime.bat          - Batch file to automate assembler code timing
  253.     pztimer.asm         - Precision Zen Timer source code
  254.     read.me             - What you are reading :-)
  255.     revision            - List of revisions to the code
  256.     timer.prj           - Borland C++ 3.0 project file (compiles main.cpp)
  257.     turboc.cfg          - Configutation file for Borland C++ 3.0
  258.     ulztimer.c          - C source for the ultra long period timer
  259.     ztimer.cpp          - C++ source for non-inline class members
  260.     ztimer.h            - Header file for the library
  261.     ztimer_s.lib        - Small model library
  262.     ztimer_c.lib        - Compact model library
  263.     ztimer_m.lib        - Medium model library
  264.     ztimer_l.lib        - Large model library
  265.     ztimer_h.lib        - Huge model library
  266.  
  267.     Assembler test files in directory test:
  268.  
  269.     test\movtst.asm     - Sample assember test code
  270.     test\movtst2.asm    - Sample assembler code to overflow PZTimer
  271.  
  272.     Turbo Pascal related files in pascal directory:
  273.  
  274.     pascal\lztimer.pas  - Source code for the TP interface unit
  275.     pascal\lztimer.tpu  - Prebuilt Turbo Pascal unit for the interface
  276.     pascal\notes        - Notes on the pascal port
  277.     pascal\main.pas     - Turbo Pascal version of sample test code
  278.  
  279.  
  280. Well, thats it. I hope you find this library useful (I use it all the time
  281. to time my graphics routines). You can contact me with comments, queries and
  282. bug fixes as show below:
  283.  
  284. Internet:
  285.  
  286. Kendall Bennett                                 kjb@godzilla.cgl.citri.edu.au
  287. Duncan Murdoch (Turbo Pascal stuff)             dmurdoch@watstat.uwaterloo.ca
  288.  
  289. Snail mail:                                     Kendall Bennett
  290.                                                 15 Stevenson Street
  291.                                                 Kew Melbourne Victoria 3101
  292.                                                 Australia
  293.  
  294.